package sealte.test.crazyjavalearning.test.IoC;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Map;
import java.util.Set;

public class MyObjectFactory {
	
	private MyXMLContext context;
	
	public MyObjectFactory() throws Exception{
		context = new MyXMLContext();
		context.initContext();
	}
	
	public Object getBeanObject(String id) throws Exception{
		String className = context.getBean(id);
		Class<?> clazz = Class.forName(className);
		Object obj = clazz.newInstance();
		Map<String,String> propertyMap = context.getProperties(id);
		if(!propertyMap.isEmpty()){
			Set<String> nameSet = propertyMap.keySet();
			for(String name:nameSet){
				String refValue = propertyMap.get(name);
				Method method = null;
				if(refValue.startsWith("ref:")){
					String ref = refValue.substring(4);
					Field field = clazz.getDeclaredField(ref);
					Class<?> type = field.getType();
					method = clazz.getMethod("set"+name.substring(0, 1).toUpperCase()+name.substring(1), 
							type);
					method.invoke(obj, getBeanObject(ref));
				}else if(refValue.startsWith("value:")){
					String value = refValue.substring(6);
					Field field = clazz.getDeclaredField(name);
					Class<?> type = field.getType();
					if(type.equals(String.class)){
						method = clazz.getMethod("set"+name.substring(0, 1).toUpperCase()+name.substring(1), 
								String.class);
						method.invoke(obj, value);
					}else if(type.getName().equals("int")){
						method = clazz.getMethod("set"+name.substring(0, 1).toUpperCase()+name.substring(1), 
								int.class);
						method.invoke(obj, new Integer(value).intValue());
					}else if(type.getName().equals("boolean")){
						method = clazz.getMethod("set"+name.substring(0, 1).toUpperCase()+name.substring(1), 
								boolean.class);
						method.invoke(obj, new Boolean(value).booleanValue());
					}else if(type.getName().equals("float")){
						method = clazz.getMethod("set"+name.substring(0, 1).toUpperCase()+name.substring(1), 
								float.class);
						method.invoke(obj, new Float(value).floatValue());
					}else if(type.getName().equals("double")){
						method = clazz.getMethod("set"+name.substring(0, 1).toUpperCase()+name.substring(1), 
								double.class);
						method.invoke(obj, new Double(value).doubleValue());
					}
				}
			}
		}
		return obj;
	}
	
}
